<?php

namespace app\shop\job;

use app\admin\model\shop\order\Export;
use app\shop\enums\notify\NotifyMessageType;
use app\shop\enums\order\OrderExportStatus;
use app\shop\service\NotifyService;
use app\shop\service\OrderExportService;
use ba\Exception;
use think\queue\Job;
use Throwable;

class OrderExportJob extends BaseJob
{
    private Export $model;

    public static string $queue = 'order_export';

    public function __construct()
    {
        parent::__construct();

        $this->model = new Export();
    }

    public function fire(Job $job, $data): void
    {
        try {
            $isJobDone = $this->doJob($job, $data);
            if ($isJobDone) {
                $this->successJob($job);
            } else {
                $this->exceptionJob($job, $data);
            }
        } catch (Throwable $e) {
            $data['error_info'] = $e->getMessage();
            $this->exceptionJob($job, $data, $e);
        }
    }

    /**
     * 导出任务
     * @param $job
     * @param $data
     * @return bool
     * @throws Exception
     */
    public function doJob($job, $data): bool
    {
        $exportRecord = $this->model->where('id', $data['id'])->findOrEmpty();
        if ($exportRecord->isEmpty()) {
            $this->success($data);
            $this->noNeedJob($job, $data);

            return true;
        }

        if ($exportRecord->status == OrderExportStatus::RUNNING) {
            $this->noNeedJob($job, ['msg' => '导入任务正在进行中']);

            return true;
        }

        if (!empty($exportRecord->last_export_file) && file_exists($exportRecord->last_export_file)) {
            $this->success($data);
            $this->noNeedJob($job, $data);

            return true;
        }

        $orderExportService = new OrderExportService();
        try {
            $orderExportService->exportOrder($exportRecord->id);

            $exportRecord->last_export_time = time();

            $exportRecord->save();

            $this->success($exportRecord->toArray());

            return true;
        } catch (Throwable $e) {
            throw new Exception($e->getMessage());
        }
    }

    public function success($data): void
    {
        $this->model->where('id', $data['id'])->update([
            'status'     => OrderExportStatus::SUCCESS,
            'error_info' => ''
        ]);

        (new NotifyService())->send(NotifyMessageType::ORDER_EXPORT, $data);
    }

    public function failed(mixed $data = [], Throwable $e = null): void
    {
        parent::failed($data, $e);

        $this->model->where('id', $data['id'])->update([
            'error_info' => $e->getMessage(),
            'status'     => OrderExportStatus::FAIL,
        ]);
    }
}